﻿using MediatR;
using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations.Schema;

namespace Apex.DomainCommons.Models
{
    /// <summary>
    /// 基础实体类，实现了实体接口和领域事件管理接口
    /// 继承BaseEntity的类，自动继承BaseEntity类中的Id属性以及领域事件管理相关的方法（例如AddDomainEvent、ClearDomainEvents等）。这意味着 继承BaseEntity的类 可以直接访问和使用BaseEntity类中定义的这些成员，无需重新实现
    /// 这种继承关系允许 继承BaseEntity的类 具有BaseEntity类的行为和属性
    /// </summary>
    public record BaseEntity : IEntity, IDomainEvents
    {
        /// <summary>
        /// 用于存储实体对象中的领域事件的私有字段
        /// [NotMapped]特性表示该字段在数据库中不会被映射为表的列，用于指示ORM工具忽略此字段
        /// </summary>
        [NotMapped]
        private List<INotification> domainEvents = new();

        /// <summary>
        /// 获取或设置实体的唯一标识符
        /// </summary>
        public Guid Id { get; protected set; } = Guid.NewGuid();

        /// <summary>
        /// 将指定的领域事件添加到事件列表
        /// </summary>
        /// <param name="eventItem">要添加的领域事件</param>
        public void AddDomainEvent(INotification eventItem)
        {
            domainEvents.Add(eventItem);
        }

        /// <summary>
        /// 如果事件列表中不存在相同的事件，则将指定的领域事件添加到事件列表中
        /// </summary>
        /// <param name="eventItem">要添加的领域事件</param>
        public void AddDomainEventIfAbsent(INotification eventItem)
        {
            if (!domainEvents.Contains(eventItem))
            {
                domainEvents.Add(eventItem);
            }
        }

        /// <summary>
        /// 清除当前实体对象中的所有领域事件
        /// </summary>
        public void ClearDomainEvents()
        {
            domainEvents.Clear();
        }

        /// <summary>
        /// 获取当前实体对象中的所有领域事件
        /// </summary>
        /// <returns>领域事件的可枚举集合。</returns>
        public IEnumerable<INotification> GetDomainEvents()
        {
            return domainEvents;
        }
    }
}
